/**
 * 给定一个字符串，请你找出其中不含有重复字符的 最长子串 的长度。
 * 首先声明三个参数，一个是无重复最长长度，一个是当前的子串，一个是最终的最长子串
  判断当前子串是否包含字母，如果不包含，将它拼接起来，并且判断长度是否大于之前判断的长度，
  如果大于，则说明有更长的子串形成，需要更新len和longestSubstring;
  如果包含了，说明当前元素和之前的元素有重复了，在这里我们找到重复元素第一次出现的索引，然后从它的后一位开始剪切这个字符串，将剪切后的字符串赋值给当前curSub，
  我这里如果你想要返回长度，就return len，如果你想要最长的无重复字符串，就return longestSubstring
  如：abca这个子串，第一个a和最后一个a重复了，我们用indexOf拿到第一个a出现的索引，向后推一位即第二位开始剪切这个字符串，则剪切之后的为bca，
  此时可以拿着这个子串继续循环看是否后面元素有重复的。
*/
let longString = 'dvdf'

// var lengthOfLongestSubstring = function(s) {
//   let len = 0
//   let longestSubstring = ''
//   let cursub = ''
//   for (let index = 0; index < s.length; index++) {
//     if(!cursub.includes(s[index])){
//       cursub += s[index]
//       if(cursub.length > len) {
//         longestSubstring = cursub
//         len = cursub.length
//       }
//     } else {
//       cursub += s[index]
//       let strIndex = cursub.indexOf(s[index])
//       cursub = cursub.slice(strIndex + 1)
//     }
//   }
//   return len
// }

// let lengthOfLongestSubstring = s => {
//   let len = 0;
//   let longestSubstring = ''
//   let cursub = ''
//   for(let ele of s) {
//     if(cursub.includes(ele)) {
//       cursub += ele
//       cursub = cursub.slice(cursub.indexOf(ele) + 1)
//     } else {
//       cursub += ele
//       if(cursub.length > len) {
//         longestSubstring = cursub
//         len = cursub.length
//       }
//     }
//   }
//   return len
// }
/**
 * 滑动窗口
 * 思路:
 * 将字符长全部遍历一遍
 * 1. 取到一个字符, 判断是否再子串内, 如果在则说明重复了. 重复了要更新子串. 子串为最后一个字符
 * 2. 子串里面不存在字符, 则将字串拼上字符. 如果子串长度大于字串最大长度, 更新字串最大长度. 更新最长字符串
 * */ 
var lengthOfLongestSubstring = function(s) {
  if(s.length == 0) return 0
  let hash = {}
  let max = 0
  let left = 0
  let moveleft = 0
  let length =  s.length
  for( let index =0; index < length; index++) {
    moveLeft = hash[s[index]]
    if(moveLeft) {
      left = Math.max(left, moveLeft)
    }
    hash[s[index]] = index + 1
    max = Math.max(max, index - left + 1)
  }
  return max
}

console.log(lengthOfLongestSubstring(longString))